use std::{collections::btree_set::Iter, env, thread};

// 闭包学习
fn main() {
    println!("Hello, world!");

    let ve1 = vec![1, 2, 3];
    let clo1 = || println!("{:?}", ve1); // 这里捕获的不是ve1 而是 &ve1

    let mut ve2 = vec![1, 2, 3];
    let clo2 = || ve2.push(4); // 这里捕获的不是 ve2 而是 &mut ve2

    let ve3 = vec![1, 2, 3];
    thread::spawn(move || println!("{:?}", ve3)) // 这里因为 move 关键字，直接移动了所有权
        .join().unwrap();



    let mut ve4 = vec![];
    let st = String::from("value");
    // 这里捕获了 st，在调用一次闭包后，st的所有权给了ve4，所以此闭包不能被二次调用
    let clo4 = || ve4.push(st);

    let mut ve5 = vec![];
    let st2 = String::from("value");
    // 这里捕获了 st，但没发生所有权转移，所以闭包可以多次调用
    let clo5 = || ve5.push(&st2);
}

fn make_a_closure(s_ref: &str) -> impl Fn() -> String {
    move || s_ref.to_string()
}

// -------- 这两种生命周期写法代表的意思是一样的 ---------
fn make_a_closure2<'a>(s_ref: &'a str) -> impl Fn() -> String + 'a {
    move || s_ref.to_string()
}

fn make_a_closure3(s_ref: & str) -> impl Fn() -> String + '_ {
    move || s_ref.to_string()
}
// ------------------------------------------

fn mark_args() {
    build(env::args());// 系统环境启动时传入的参数
}
// 传入 Iterator 参数
fn build(mut args: impl Iterator<Item = String>) {
    args.next(); // 第一个是程序自己
} 